// Copyright (C) 2023 即时通讯网(52im.net) & Jack Jiang.
// The RainbowChat Project. All rights reserved.
// 
// 【本产品为著作权产品，合法授权后请放心使用，禁止外传！】
// 【本次授权给：<北京小羊驼科技有限公司>，授权编号：<NT231212144350>，代码指纹：<A.702363430.550>，技术对接人微信：<ID: wxid_wbyootvkdcgj22>】
// 【授权寄送：<收件：苏先生、地址：北京市大兴区北京密码西区6号楼1单元301、电话：18613885610、邮箱：bd@huiyuanxiang-inc.com>】
// 
// 【本系列产品在国家版权局的著作权登记信息如下】：
// 1）国家版权局登记名(简称)和权证号：RainbowChat    （证书号：软著登字第1220494号、登记号：2016SR041877）
// 2）国家版权局登记名(简称)和权证号：RainbowChat-Web（证书号：软著登字第3743440号、登记号：2019SR0322683）
// 3）国家版权局登记名(简称)和权证号：RainbowAV      （证书号：软著登字第2262004号、登记号：2017SR676720）
// 4）国家版权局登记名(简称)和权证号：MobileIMSDK-Web（证书号：软著登字第2262073号、登记号：2017SR676789）
// 5）国家版权局登记名(简称)和权证号：MobileIMSDK    （证书号：软著登字第1220581号、登记号：2016SR041964）
// * 著作权所有人：江顺/苏州网际时代信息科技有限公司
// 
// 【违法或违规使用投诉和举报方式】：
// 联系邮件：jack.jiang@52im.net
// 联系微信：hellojackjiang
// 联系QQ号：413980957
// 授权说明：http://www.52im.net/thread-1115-1-1.html
// 官方社区：http://www.52im.net
package com.x52im.rbchat.logic.main;

import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.view.MotionEvent;

import com.eva.android.widget.ViewPager4Fixed;
import com.eva.android.widget.WidgetUtils;
import com.google.android.material.bottomnavigation.BottomNavigationItemView;
import com.google.android.material.bottomnavigation.BottomNavigationMenuView;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.navigation.NavigationBarView;
import com.x52im.mall.MainFragment;
import com.x52im.rbchat.MyApplication;
import com.x52im.rbchat.R;
import com.x52im.rbchat.logic.alarm.AlarmsFragment;
import com.x52im.rbchat.logic.alarm.impl.AlarmsViewModel;
import com.x52im.rbchat.logic.contact.FriendListFragment;
import com.x52im.rbchat.logic.contact.viewmodel.FriendsReqViewModel;
import com.x52im.rbchat.logic.main.mainimpl.AbstractMainActivity;
import com.x52im.rbchat.logic.main.mainimpl.AlarmsFragmentTitleWrapper;
import com.x52im.rbchat.logic.main.mainimpl.FriendListFragmentTitleWrapper;
import com.x52im.rbchat.logic.main.mainimpl.GroupsFragmentTitleWrapper;
import com.x52im.rbchat.logic.main.mainimpl.MainFragmentPagerAdapter;
import com.x52im.rbchat.logic.main.mainimpl.MallFragmentTitleWrapper;
import com.x52im.rbchat.logic.main.mainimpl.MyFragmentTitleWrapper;
import com.x52im.rbchat.logic.main.mainimpl.NavigationBageViewWrapper;
import com.x52im.rbchat.logic.more.MyFragment;
import com.x52im.rbchat.logic.sns_group.GroupsFragment;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.viewpager.widget.ViewPager;

/**
 * RainbowChat的主界面实现类。
 * <p>
 * 当前，主界面的UI组织方式是：单Activity+多个子Fragment基于ViewPager方式进行切换。
 *
 * @author Jack Jiang
 * @since 8.0
 */
public class MainActivity extends AbstractMainActivity {

    private final static String TAG = MainActivity.class.getSimpleName();

    /** 子fragment集合对象 */
    private List<Fragment> mFragmentList = new ArrayList<>(5);

    /** 底部导航栏 */
    private BottomNavigationView bottomNavigationView;
    /** 底部导航栏上"消息"未读消息数角标组件 */
    private NavigationBageViewWrapper unreadMsgCountBadgeView = null;
    /** 底部导航栏上"好友"未读请求数角标组件 */
    private NavigationBageViewWrapper unreadFriendReqCountBadgeView = null;

    /** 用于实现各子Fragment切换的ViewPager对象 */
    private ViewPager4Fixed contentViewPager;

//    /** 内容父布局对象引用 */
//    private LinearLayout contentLinearLayout;

    /** "消息"子fragment */
    private AlarmsFragment alarmsFragment = null;
    /** "好友"子fragment */
    private FriendListFragment friendListFragment = null;
    /** "群聊"子fragment */
    private GroupsFragment groupsFragment = null;

    /** "消息"子fragment的标题栏封装对象 */
    private AlarmsFragmentTitleWrapper alarmsFragmentTitleWrapper = null;
    /** "好友"子fragment的标题栏封装对象 */
    private FriendListFragmentTitleWrapper friendListFragmentTitleWrapper = null;
    /** "群聊"子fragment的标题栏封装对象 */
    private GroupsFragmentTitleWrapper groupsFragmentTitleWrapper = null;
    /** "商城"子fragment的标题栏封装对象 */
    private MallFragmentTitleWrapper mallFragmentTitleWrapper = null;
    /** "我的"子fragment的标题栏封装对象 */
    private MyFragmentTitleWrapper myFragmentTitleWrapper = null;

    /** ViewModel："消息"列表数据ViewModel对象 */
    private AlarmsViewModel viewModel4Alarms = null;
    /** ViewModel：加好友请求数据ViewModel对象 */
    private FriendsReqViewModel viewModel4FriendReq = null;

    // 本方法将在Activity每次从后台会到前台时被调用（处于后台是指：用户按了home键、
    // 或打开了另一个Activity等等让本Activity失去焦点的情况），如有疑问请参见Activity的生命周期资料
    @Override
    public void onResume() {
        super.onResume();

        // 刷新标题和底部导航栏上的未读消息总数的显示
        if(viewModel4Alarms != null)
            viewModel4Alarms.loadAlarmsUnread();
        // 刷新"商城"标题栏上的购物车内商量数量显示
        if(currentIsMallFragment())
            mallFragmentTitleWrapper.refreshShopCarCountShow();
        // 刷新加好友请求未读总数的显示
        if(viewModel4FriendReq != null)
            viewModel4FriendReq.reloadUnreadCountData();;
    }

    /**
     * 整个界面的总初始化方法。子类覆盖此方法是为了加入自已的额外逻辑。
     *
     * @param savedInstanceState na
     */
    protected void init(Bundle savedInstanceState){
        super.init(savedInstanceState);
        initLiveDataObserver();
    }

    /**
     * 本方法由父类的 {@link #init(Bundle)} 调用，子类可在此方法中实现ui的初始化。
     */
    @Override
    protected void initViews(Bundle savedInstanceState){

        //* 设定自定义标题栏（设定此值即意味着开启自定义标题栏的使用，必须要在setContentView前设定）
        customeTitleBarResId = R.id.main_activity_titleBar;
        //* 养成良好习惯：首先设置主layout，确保后绪的操作中使用到的组件都可以被find到
        setContentView(R.layout.main_activity);

        //* 按back键回到桌面
        this.goHomeOnBackPressed = true;

        //* 自定义标题组件配置
        this.getCustomeTitleBar().setLeftBackButtonVisible(false);

        //* 主ui组件
        bottomNavigationView = findViewById(R.id.bottomNavigationView);
        contentViewPager = findViewById(R.id.contentViewPager);
//      contentLinearLayout = findViewById(R.id.contentLinearLayout);

        //* 将要在ViewPager中切换的子fragment
        mFragmentList.add(alarmsFragment = new AlarmsFragment());
        mFragmentList.add(friendListFragment = new FriendListFragment());
        mFragmentList.add(groupsFragment = new GroupsFragment());
        mFragmentList.add(new MainFragment());
        mFragmentList.add(new MyFragment());

        //* 内容页的ViewPager对象设置
        // 设置ViewPager的最大缓存页面
        contentViewPager.setOffscreenPageLimit(4);// 3
        contentViewPager.setAdapter(new MainFragmentPagerAdapter(getSupportFragmentManager(), mFragmentList));
        contentViewPager.addOnPageChangeListener(new ViewPagerChangeListener());

        //* 底部导航栏的基本设置
        // 以下设置解决BottomNavigationView组件会默认把item的图片颜色处理灰色处理（很难看）
        bottomNavigationView.setItemIconTintList(null);
        // 设置导航栏item的选中事件处理
        bottomNavigationView.setOnItemSelectedListener(new NavigationBarItemSelectedListener());

        //* BottomNavigationView组件item的id（这个id必须与 res/layout/main_bottom_navigation_items.xml 中定义的顺序绝对一致）
        List<Integer> bottomNavigationItemIds = Arrays.asList(R.id.main_bottom_nav_alarms, R.id.main_bottom_nav_friends
                , R.id.main_bottom_nav_groups, R.id.main_bottom_nav_mall, R.id.main_bottom_nav_my);
        // 清除BottomNavigationView组件item长按时的toast提示（那个太丑了）
        WidgetUtils.clearBottomNavigationViewToast(bottomNavigationView, bottomNavigationItemIds);

        //* 实例化各子Fragment对象
        alarmsFragmentTitleWrapper = new AlarmsFragmentTitleWrapper(this);
        friendListFragmentTitleWrapper = new FriendListFragmentTitleWrapper(this, friendListFragment);
        groupsFragmentTitleWrapper = new GroupsFragmentTitleWrapper(this, groupsFragment);
        mallFragmentTitleWrapper = new MallFragmentTitleWrapper(this);
        myFragmentTitleWrapper = new MyFragmentTitleWrapper(this);

        //* 默认加载首页"消息"fragment的标题栏（包括标题文本、标题栏上的功能按钮等）
        alarmsFragmentTitleWrapper.loadTitle();
    }

    /**
     * 本方法由父类的 {@link #init(Bundle)} 调用，子类可在此方法中为各UI功能组件增加事件临听。
     */
    @Override
    protected void initListeners() {
        //
    }

    /**
     * 初始化相关ViewModel及其观察者等。
     */
    private void initLiveDataObserver(){
        Log.i(TAG, "@@@@4【AlarmsViewModel】MainActivity中的initLiveDataObserver，被调用了？？？？？？");

        // 拿到本类对应的ViewModel对象，实现MVVM架构
        this.viewModel4Alarms = new ViewModelProvider(this).get(AlarmsViewModel.class);
        this.viewModel4FriendReq = new ViewModelProvider(this).get(FriendsReqViewModel.class);

        // 数据模型LiveData绑定："消息"列表数据模型变动观察者，由此此观察者来完成ui的刷新（这样就能保证最新消息能即时显示在界面上了）
        this.viewModel4Alarms.getAlarmsLiveData().observe(this, alarmsData -> {
            Log.i(TAG, "@@@ YY位置MainActivity中的viewModel4Alarms.getAlarmsLiveData()观察者被通知了，viewModel4Alarms.hash="+viewModel4Alarms.hashCode());
            // 当列表中消息数据变动（可能是新增、删除、替换等）时，就同时提请刷新未读消息总数
//            refreshUnreadMsgCount();
            viewModel4Alarms.loadAlarmsUnread();
        });

        // 数据模型LiveData绑定："消息"列表中未读消息总数刷新观察者，由此观察者来刷新"消息"标题栏、底部导航栏上"消息"上的未读总数
        this.viewModel4Alarms.getAlarmsUnreadLoadedLiveData().observe(this, totalUnreadNum -> {
            Log.i(TAG, "@@@ YY位置MainActivity中的viewModel4Alarms.getAlarmsUnreadLoadedLiveData("+totalUnreadNum+")观察者被通知了，viewModel4Alarms.hash="+viewModel4Alarms.hashCode());
            // 刷新ui显示
            refreshUnreadMsgCount(totalUnreadNum);
        });

        // 数据模型LiveData绑定：实现加好友请求未读数发生变动时接收通知，以便在主界面底部导航栏上显示出未读总数
        this.viewModel4FriendReq.getUnreadCountChangedLiveData().observe(this, unreadreqCount -> {
            Log.i(TAG, "@@@ YY位置MainActivity中的viewModel4FriendReq.getUnreadCountChangedLiveData("+unreadreqCount+")观察者被通知了，viewModel4Alarms.hash="+viewModel4Alarms.hashCode());
            // 刷新ui显示
            refreshUnreadFriendReqCount(unreadreqCount);
        });
    }

    /**
     * 长按事件处理。
     *
     * @param ev 长按事件对象
     * @return boolean Return true if this event was consumed
     */
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        // 如果当前显示的页是"消息"页，则把Activity的长按事件传递给它的fragment对象
        if(currentIsAlarmsFragment()) {
            if (alarmsFragment != null) {
                // 将长按事件传递到子fragment中（Fragment是没有长按事件的）
                alarmsFragment.dispatchTouchEvent(ev);
            }
        }
        return super.dispatchTouchEvent(ev);
    }

    /**
     * 当前正在显示的子fragment是"消息"界面。
     *
     * @return true表示是，否则不是
     * @see #currentIsFriendListFragment(int)
     */
    private boolean currentIsAlarmsFragment(){
        return contentViewPager != null && contentViewPager.getCurrentItem() == 0;
    }

    /**
     * 当前正在显示的子fragment是"好友"界面。
     *
     * @param position 当前viewpager索引
     * @return true表示是，否则不是
     */
    private boolean currentIsFriendListFragment(int position){
        return position == 1;
    }

    /**
     * 当前正在显示的子fragment是"好友"界面。
     *
     * @return true表示是，否则不是
     */
    private boolean currentIsFriendListFragment(){
        return contentViewPager != null && currentIsFriendListFragment(contentViewPager.getCurrentItem());
    }

    /**
     * 当前正在显示的子fragment是"群聊"界面。
     *
     * @return true表示是，否则不是
     */
    private boolean currentIsGroupsFragment(){
        return contentViewPager != null && contentViewPager.getCurrentItem() == 2;
    }

    /**
     * 当前正在显示的子fragment是"商城"界面。
     *
     * @return true表示是，否则不是
     */
    private boolean currentIsMallFragment(){
        return contentViewPager != null && contentViewPager.getCurrentItem() == 3;
    }

    /**
     * 当前正在显示的子fragment是"我的"界面。
     *
     * @return true表示是，否则不是
     */
    private boolean currentIsMyFragment(){
        return contentViewPager != null && contentViewPager.getCurrentItem() == 4;
    }

    /**
     * 刷新未读消息数的显示。
     *
     * @param totalUnreadNum 最新的总未读消息数，大于0时表示设置，否则表示清除未读数的显示
     */
    private void refreshUnreadMsgCount(int totalUnreadNum){
        if(unreadMsgCountBadgeView == null){
            BottomNavigationMenuView bottomNavigationMenuView = ((BottomNavigationMenuView) bottomNavigationView.getChildAt(0));
            BottomNavigationItemView itemView = (BottomNavigationItemView)(bottomNavigationMenuView.getChildAt(0));
            unreadMsgCountBadgeView = new NavigationBageViewWrapper(this, itemView);
            // 添加到导航栏的Tab上
            itemView.addView(unreadMsgCountBadgeView.getBadgeLayoutView());
        }

        // 未读消息总数
        if(totalUnreadNum > 0) {
            // 设置导航栏tab上的未计数角标
            unreadMsgCountBadgeView.setNumber(totalUnreadNum);
        } else{
            // 清除导航栏tab上的未计数角标显示内容
            unreadMsgCountBadgeView.setNumber(0);
        }

        // 更新标题上的未读消息显示
        refreshUnreadMsgCount4Title(totalUnreadNum);
    }

    /**
     * 刷新标题栏上的未读消息数的显示。
     *
     * @see #refreshUnreadMsgCount4Title(int)
     */
    private void refreshUnreadMsgCount4Title(){
        // 未读消息总数
        int totalUnreadNum = MyApplication.getInstance2().getIMClientManager().getAlarmsProvider().getTotalFlagNum();
        refreshUnreadMsgCount4Title(totalUnreadNum);
    }

    /**
     * 刷新标题栏上的未读消息数的显示。
     *
     * @param count 未读消息总数
     */
    private void refreshUnreadMsgCount4Title(int count){
        // 默认"消息"页标题
        String newAlarmsTitle = $$(R.string.portal_activity_news);
        if(count > 0) {
            // 加上了未读的"消息"页标题
            newAlarmsTitle = newAlarmsTitle+" ("+count+")";
        }

        // 更新标题上的未读消息显示
        if(currentIsAlarmsFragment()){
            setTitle(newAlarmsTitle);
        }
    }

    /**
     * 刷新未读了友请求数的显示。
     *
     * @param unreadFriendReqCount 未读好友请求总数，，大于0时表示设置，否则表示清除显示
     * @see NavigationBageViewWrapper
     */
    private void refreshUnreadFriendReqCount(int unreadFriendReqCount){
        if(unreadFriendReqCountBadgeView == null){
            // 取出主界面底部导航栏上的"好友"tab item实例对象引用
            BottomNavigationMenuView bottomNavigationMenuView = ((BottomNavigationMenuView) bottomNavigationView.getChildAt(0));
            BottomNavigationItemView itemView = (BottomNavigationItemView)(bottomNavigationMenuView.getChildAt(1));
            // 未读好友请求数气泡封装实现类
            unreadFriendReqCountBadgeView = new NavigationBageViewWrapper(this, itemView);
            // 添加到导航栏的Tab上
            itemView.addView(unreadFriendReqCountBadgeView.getBadgeLayoutView());
        }

        // 未读消息总数
        int totalUnreadNum = unreadFriendReqCount;//MyApplication.getInstance2().getIMClientManager().getAlarmsProvider().getTotalFlagNum();
        if(totalUnreadNum > 0) {
            // 设置导航栏tab上的未计数角标
            unreadFriendReqCountBadgeView.setNumber(totalUnreadNum);
        }
        else{
            // 清除导航栏tab上的未计数角标显示内容
            unreadFriendReqCountBadgeView.setNumber(0);
        }
    }


    /**
     * 底部导航栏item的选中事件监听者实现类（实现导航栏的tab的切换时自动切换它对应的fragment页面显示）.
     */
    private class NavigationBarItemSelectedListener implements NavigationBarView.OnItemSelectedListener{
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            Log.i("AAAAA", "【111-1】bottomNavigationView.setOnItemSelectedListener中，选中的item.getItemId()="
                    +item.getItemId()+", bottomNavigationView.getSelectedItemId()?"+bottomNavigationView.getSelectedItemId());
            switch (item.getItemId()) {
                case R.id.main_bottom_nav_alarms:
                    contentViewPager.setCurrentItem(0, false);
                    break;
                case R.id.main_bottom_nav_friends:
                    contentViewPager.setCurrentItem(1, false);
                    break;
                case R.id.main_bottom_nav_groups:
                    contentViewPager.setCurrentItem(2, false);
                    break;
                case R.id.main_bottom_nav_mall:
                    contentViewPager.setCurrentItem(3, false);
                    break;
                case R.id.main_bottom_nav_my:
                    contentViewPager.setCurrentItem(4, false);
                    break;
                default:
                    break;
            }
            return true;
        }
    }

    /**
     * ViewPager切换事件监听实现类（实现子Fragment的左右滑动切换）。
     */
    private class ViewPagerChangeListener implements ViewPager.OnPageChangeListener{

        /**
         * 当ViewPager页面在滑动的时候会调用此方法。
         *
         * @param position 当前页面索引，即你点击滑动的页面
         * @param positionOffset 当前页面偏移的百分比
         * @param positionOffsetPixels 当前页面偏移的像素位置
         */
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            // ViewPager滚动时清除字母快速检索组件选中状态，不然主页ViewPager左右滑动时，此选中时显地的ui无法自动消失
            if(currentIsFriendListFragment(position)) {
                friendListFragment.clearLetterIndexSelected();
            }
        }

        /**
         * ViewPager的页面选择完毕时的回调。
         *
         * @param position 当前选中的页面索引
         */
        @Override
        public void onPageSelected(int position) {

            Log.i("AAAAA", "【111-2】MainFragmentPagerChangeListener.onPageSelected，选中的position="
                    +position +", contentViewPager.getCurrentItem()="+contentViewPager.getCurrentItem());

            if (currentIsAlarmsFragment()) {
                bottomNavigationView.setSelectedItemId(R.id.main_bottom_nav_alarms);
                alarmsFragmentTitleWrapper.loadTitle();
                setTitle(R.string.portal_activity_news);
                refreshUnreadMsgCount4Title();
            } else if (currentIsFriendListFragment()) {
                bottomNavigationView.setSelectedItemId(R.id.main_bottom_nav_friends);
                friendListFragmentTitleWrapper.loadTitle();
                setTitle(R.string.portal_activity_partner);
            } else if (currentIsGroupsFragment()) {
                bottomNavigationView.setSelectedItemId(R.id.main_bottom_nav_groups);
                groupsFragmentTitleWrapper.loadTitle();
                setTitle(R.string.portal_activity_group);
            } else if (currentIsMallFragment()) {
                bottomNavigationView.setSelectedItemId(R.id.main_bottom_nav_mall);
                mallFragmentTitleWrapper.loadTitle();
                setTitle(R.string.portal_activity_mall);
            } else if (currentIsMyFragment()) {
                bottomNavigationView.setSelectedItemId(R.id.main_bottom_nav_my);
                myFragmentTitleWrapper.loadTitle();
                setTitle(R.string.portal_activity_more);
            } else {
                Log.e(TAG, "无效的position=" + position);
            }

            // ViewPager滚动结束后才显示字母快速检索组件，不然ui上不太好看
            friendListFragment.showLetterIndexBar(currentIsFriendListFragment());

            // 如果当前fragment不是"商城"界面
            if(!currentIsMallFragment()){
                // 清除购物车的未读数显示等
                mallFragmentTitleWrapper.clearShopCarCountView();
            }
        }

        /**
         * ViewPager滚动过程中隐藏字母快速检索组件，不然ui上不太好看
         *
         * @param state ViewPager的状态
         */
        @Override
        public void onPageScrollStateChanged(int state) {
            friendListFragment.showLetterIndexBar(state == ViewPager.SCROLL_STATE_IDLE);
        }
    }
}